/**
 * WebSocket服务封装
 * 提供基于user_id的连接和消息发送功能
 */

class WebSocketService {
  constructor() {
    this.ws = null;
    this.reconnectAttempts = 0;
    this.maxReconnectAttempts = 5;
    this.reconnectInterval = 3000;
    this.isManualClose = false;
  }

  /**
   * 创建WebSocket连接
   * @param {string} userId - 用户ID
   * @param {string} wsUrl - WebSocket服务器地址，默认为本地8080端口
   */
  connect(userId, wsUrl = 'ws://http://127.0.0.1:8004/ws/connect') {
    // 如果已连接，先关闭
    if (this.ws && this.ws.readyState === WebSocket.OPEN) {
      console.warn('WebSocket连接已存在，正在关闭旧连接');
      this.disconnect();
    }

    // 构建连接URL
    const connectionUrl = `${wsUrl}?user_id=${userId}`;
    this.isManualClose = false;

    try {
      this.ws = new WebSocket(connectionUrl);

      // 连接打开时的回调
      this.ws.onopen = (event) => {
        console.log('WebSocket连接已打开', event);
        this.reconnectAttempts = 0; // 重置重连次数
      };

      // 接收消息时的回调
      this.ws.onmessage = (event) => {
        try {
          const message = JSON.parse(event.data);
          console.log('收到消息:', message);
          this.onMessageReceived(message);
        } catch (error) {
          console.error('解析消息失败:', error);
        }
      };

      // 连接关闭时的回调
      this.ws.onclose = (event) => {
        console.log('WebSocket连接已关闭', event);
        // 如果不是手动关闭且未超过最大重连次数，则尝试重连
        if (!this.isManualClose && this.reconnectAttempts < this.maxReconnectAttempts) {
          this._reconnect(userId, wsUrl);
        }
      };

      // 连接错误时的回调
      this.ws.onerror = (error) => {
        console.error('WebSocket错误:', error);
      };

    } catch (error) {
      console.error('WebSocket连接创建失败:', error);
    }
  }

  /**
   * 发送广播消息
   * @param {string} sender - 发送者ID
   * @param {string} content - 消息内容
   * @param {string} type - 消息类型，默认为'text'
   */
  sendBroadcastMessage(sender, content, type = 'text') {
    const message = {
      sender: sender,
      content: content,
      type: type,
      timestamp: Date.now()
    };
    this._send(message);
  }

  /**
   * 发送私有消息
   * @param {string} sender - 发送者ID
   * @param {string} recipient - 接收者ID
   * @param {string} content - 消息内容
   * @param {string} type - 消息类型，默认为'text'
   */
  sendPrivateMessage(sender, recipient, content, type = 'text') {
    const message = {
      sender: sender,
      recipient: recipient,
      content: content,
      type: type,
      timestamp: Date.now()
    };
    this._send(message);
  }

  /**
   * 发送消息的内部方法
   * @private
   * @param {object} message - 消息对象
   */
  _send(message) {
    if (this.ws && this.ws.readyState === WebSocket.OPEN) {
      this.ws.send(JSON.stringify(message));
    } else {
      console.error('WebSocket未连接，无法发送消息');
    }
  }

  /**
   * 重连机制
   * @private
   * @param {string} userId - 用户ID
   * @param {string} wsUrl - WebSocket服务器地址
   */
  _reconnect(userId, wsUrl) {
    this.reconnectAttempts++;
    console.log(`尝试第${this.reconnectAttempts}次重连...`);
    
    setTimeout(() => {
      this.connect(userId, wsUrl);
    }, this.reconnectInterval * this.reconnectAttempts);
  }

  /**
   * 断开连接
   */
  disconnect() {
    this.isManualClose = true;
    if (this.ws) {
      this.ws.close();
      this.ws = null;
    }
  }

  /**
   * 消息接收处理方法（可被子类或调用者重写）
   * @param {object} message - 接收到的消息
   */
  onMessageReceived(message) {
    // 默认实现，可以在使用时重写此方法来处理收到的消息
    console.log('消息处理:', message);
    // 在这里可以添加消息处理逻辑，例如显示在聊天界面
  }

  /**
   * 获取连接状态
   * @returns {number|null} WebSocket连接状态，null表示未初始化
   */
  getConnectionState() {
    return this.ws ? this.ws.readyState : null;
  }

  /**
   * 判断是否已连接
   * @returns {boolean} 是否已连接
   */
  isConnected() {
    return this.ws && this.ws.readyState === WebSocket.OPEN;
  }
}

// 导出单例实例
export default new WebSocketService();